Component({
  behaviors: [require('../common/share-behavior').default],
  innerInterval: 0,
  videoId: -1,
  properties: {
    a: Number,
    colData: {
      type: Array,
      value: []
    },
    gltfListRaw: {
      type: Array,
      value: [],
    },
    imageListRaw: {
      type: Array,
      value: [],
    },
    videoListRaw: {
      type: Array,
      value: [],
    },
  },
  data: {
    arReady: false,
    assetResources: {},
    audioIdList: {},
    audioLoaded: false,
    col: [],

    gltfLoaded: false,
    gltfIdList: [],
    imageLoaded: false,
    imageIdList: [],
    isTracking: false,
    isTracked: false,
    loaded: false,
    loadedAssets: [],
    loadedIdRes: [],
    loading: false,
    markerResources: {},
    markerIdList: [],
    markerWidth: 0,
    markerHeight: 0,
    resourceList: {},
    resourceLoadedId: [],

    videoIdList: [],
    videoLoaded: false,
    videoRatioLoaded: false
  },
  observers: {
    gltfListRaw(newVal) {
      this._releaseGLTF();
      this.registerResource('gltf', newVal);

    },
    videoListRaw(newVal) {
      this._releaseVideo();
      this.registerResource('video', newVal);

    },
    imageListRaw(newVal) {
      this._releaseImage();
      this.registerResource('image', newVal);

    },
    colData(newVal) {
      console.log('observers colData');
      if (newVal.length > 0) {
        this._setCol(newVal);
      }
    },
  },
  lifetimes: {
    attached() {
      const colData = this.data.colData;
      // console.log('attached colData', colData);
    },
    detached() { }
  },
  methods: {
    _setCol(colData) {
      this.setData({
        col: colData,
      });
      // console.log('col ', this.data.col);
    },
    registerResource(type, data) {
      // console.log(`registerResource ${type}`, data);
      const resIdList = this.data.resourceList;

      const gltfIdList = this.data.gltfIdList;
      const videoIdList = this.data.videoIdList;
      const imageIdList = this.data.imageIdList;
      data.map(item => {
        resIdList[item.id] = item;
        switch (type) {
          case 'gltf':
            gltfIdList.push(item.id);
            break;
          case 'video':
            console.log('video type', item.type);

            videoIdList.push(item.id);
            break;
          case 'image':
            imageIdList.push(item.id);
            break;
          default:
            console.log(`registerResource ${type} no match`);
            break;
        }
      });
      this.setData({
        resourceList: resIdList,
        gltfIdList: gltfIdList,
        videoIdList: videoIdList,
        imageIdList: imageIdList
      })
      // console.log('registerResource resourceList', this.data.resourceList);
    },

    _parseColdata(colData) {
      let marRes = {};
      const reslist = this.data.resourceList;
      // console.log('reslist', reslist);
      const marIds = this.data.markerIdList || [];
      colData.forEach(ele => {
        if (ele.resources.length > 0) {
          // console.log('col item：' + ele.id + ' has resource');
          let markerResource = [];
          ele.resources.forEach(resId => {
            // console.log('col resAsset id:' + resId);
            const resItem = reslist[resId];
            // console.log('resItem:', resItem);
            const type = this._resType(resId);
            let marItemResource = this._getMarResItem(type, resItem);
            // console.log('marItemResource:', marItemResource);
            markerResource.push(marItemResource);
            // console.log('Updated markerResource:', markerResource);
          });
          marRes[ele.id] = markerResource;
          marIds.push(ele.id);
        } else {
          console.log('col item：' + ele.id + ' has no resource');
        }
      });
      // console.log('Updated marRes:', marRes);
      this.setData({
        resourceList: reslist,
        markerResources: marRes
      });
      console.log('data', this.data);
    },
    _resType(resId) {
      let resType = '';
      if (this.data.videoIdList.includes(resId)) {
        resType = 'video';
      } else if (this.data.gltfIdList.includes(resId)) {
        resType = 'gltf';
      } else if (this.data.imageIdList.includes(resId)) {
        resType = 'image';
      } else {
        console.log(`resId ${resId}  error`);
      }
      return resType;
    },

    _getMarResItem(type, data) {
      let pos = this._getXYZString(data.position);
      let ros = this._getXYZString(data.rotation);
      let scale = this._getScaleString(data.scale);
      let newData = {};
      if (type == 'video') {
        console.log('video:', data.type);
        let tetype = 'video';
        if (data.type !== 'normal') {
          tetype = 'video' + '_' + data.type;
        }
        newData = {
          id: data.id, type: tetype, assetId: `${type}-${data.id}`, matId: `mat-video-${data.id}`, loadShow: true,
          matShow: true, src: data.src, position: pos, rotation: ros, scale: scale, width: data.width, height: data.height, options: { autoplay: data.autoplay, loop: data.loop }, ops: `loop:${data.loop};autoplay:${data.autoplay};`
        };
      } else if (type == 'gltf') {
        newData = { id: `${type}-${data.id}`, type: type, matId: '', loadShow: true, matShow: false, src: data.src, position: pos, rotation: ros, scale: scale };
      } else if (type == 'image') {
        newData = { id: `${type}-${data.id}`, type: type, src: data.src, position: pos, rotation: ros, scale: scale };
      } else {
        console.log(`type:${type} error`);
      }
      return newData;
    },
    _getScaleString(scale) {
      if (typeof scale === 'string' && scale.includes(',')) {
        // 如果是字符串且包含逗号，处理字符串
        return scale.split(',').map(value => parseFloat(value.trim()).toFixed(1)).join(' ');
      } else {
        // 如果是数字或不包含逗号的字符串，使用相同的值
        return `${scale} ${scale} ${scale}`;
      }
    },
    _getXYZString(xyzObj) {
      // 从对象中提取x, y, z的值，并去掉可能的空格
      const x = xyzObj.x.toString().trim();
      const y = xyzObj.y.toString().trim();
      const z = xyzObj.z.toString().trim();

      // 返回格式化后的字符串
      return `${x} ${y} ${z}`;
    },
    handleReady({ detail }) {
      console.log('xr-handleReady');
      const xrScene = this.scene = detail.value;

      console.log('xr-scene', xrScene);
      // 加载场景资源
      // console.log('data', this.data);

      this._parseColdata(this.data.col);
      console.log('data', this.data);
      // if (this.data.assetResources.length > 0) {
      //   console.log('load assetResources list:', this.data.assetResources);
      //   const resList = this.data.assetResources;
      //   resList.forEach(item => {
      //     // console.log('assetResource item: ', item.type)
      //     switch (item.type) {
      //       case 'gltf':
      //         console.log('gltf item info: ', item)
      //         // try {
      //         //   this._loadGLTF(item);
      //         //   console.log('gltf asset ' + item.id + ' loaded');
      //         // } catch (err) {
      //         //   console.log('[gltf load] error: ', err)
      //         // }
      //         break;
      //       case 'video-texture':
      //         console.log('video item info: ', item)
      //         // try {
      //         //   this._loadVideoSingle(item);
      //         //   console.log('video asset ' + item.id + ' loaded');
      //         // } catch (err) {
      //         //   console.log('[video load] error: ', err)
      //         // }
      //         break;
      //       case 'img':
      //         console.log('img item info: ', item);
      //         break;
      //       default:
      //         console.log('unknow assetResource item: ', item.type)
      //         console.log('unknown asset type: ', item.type);
      //         break;
      //     }
      //   });
      //   this.setData({
      //     videoLoaded: true,
      //   });
      // }
    },


    getResourceType(resId) {
      let type = '';
      const gultfIds = this.data.gltfIdList;
      if (gultfIds.includes(resId)) {
        type = 'gltf';
      }
      const videoIds = this.data.videoIdList;
      if (videoIds.includes(resId)) {
        type = 'video';
      }
      const imageIds = this.data.imageIdList;
      if (imageIds.includes(resId)) {
        type = 'image';
      }
      return type;
    },
    handleAssetsProgress: function ({ detail }) {
      console.log('assets progress', detail.value);
    },
    handleAssetsLoaded: function ({ detail }) {
      console.log('assets loaded', detail.value.assets);
      if (!detail || !detail.value || !detail.value.assets) {
        console.error('Invalid detail object:', detail);
        return;
      }
      const assets = this.data.loadedAssets || []; // 确保loadedAssets存在，如果不存在则初始化为空对象
      const assetIds = this.data.loadedIdRes;
      // 获取 assets 对象
      const assetDets = detail.value.assets;

      // 使用 Object.keys 遍历 assets 对象的键
      Object.keys(assetDets).forEach(key => {
        const asset = assetDets[key];
        // console.log('Asset:', asset);
        assets.push(asset);
        // console.log('Asset ID:', asset.assetId);
        assetIds.push(asset.assetId);
      });
      // 更新组件数据
      this.setData({
        loaded: true,
        loadedAssets: assets,
        loadedIdRes: assetIds
      });
      console.log('loadedAssets', assets);
      console.log('loadedIdRes', assetIds);
    },
    handleGLTFLoaded({ detail }) {
      const el = detail.value.target;
      const gltf = el.getComponent("gltf");
      const animator = el.getComponent("animator");
      console.log("gltf:", gltf);
      console.log("animator:", animator);
    },
    handleTouchCube: function ({ detail }) {
      const target = detail.value.target;
      console.log(target.material);
      console.log(target.uniforms);
      console.log(target.getData('uniforms'));

      // console.log(target.model);
      // const xrSystem = wx.getXrFrameSystem();
      // const video = this.scene.assets.getAsset('video-texture', 'cat');

      // console.log(video.state);
      // if (!video) {
      //   return;
      // }
      // if (video.state === xrSystem.EVideoState.Idle) {
      //   video.play();
      // } else if (video.state === xrSystem.EVideoState.Playing) {
      //   video.pause();
      // } else if (video.state === xrSystem.EVideoState.Paused) {
      //   video.resume();
      // }
    },
    async _loadGLTF(gltfItem) {
      console.log('load sigle gltfItem:', gltfItem);
      const scene = this.scene;
      console.log('scene:', scene);
      const { value: model } = await scene.assets.loadAsset({ type: 'gltf', assetId: gltfItem.id, src: gltfItem.src });
      console.log('glTF asset loaded', model);
      const assets = this.data.loadedAssets;
      assets.push(gltfItem);
      const assetIds = this.data.loadedIdRes;
      assetIds.push(gltfItem.id);

      this.setData({
        loadedIdRes: assetIds,
        loadedAssets: assets,
        gltfLoaded: true
      });
    },
    async _loadGLTFs(gltfList) {
      console.log('load gltfs:', gltfList);
      const scene = this.scene

      if (gltfList.length > 0) {
        const gltfIdList = [];
        const gltfModel = await Promise.all(gltfList.map((gltfItem) => {
          gltfIdList.push(gltfItem.id)
          const gtltfPromise = scene.assets.loadAsset({
            type: 'gltf',
            assetId: `gltf-${gltfItem.id}`,
            src: gltfItem.src,
          })
          return gtltfPromise;
        }));

        console.log('glTF asset loaded')
        this.setData({
          gltfIdList: gltfIdList,
          gltfLoaded: true
        })
      } else {
        this.setData({
          gltfIdList: [],
          gltfLoaded: false,
        });
      }
    },
    async _loadVideos(videoList) {
      console.log('load videos:', videoList);
      const scene = this.scene
      if (videoList.length > 0) {
        const videoIdList = [];
        const videos = await Promise.all(videoList.map((videoItem) => {
          videoIdList.push(videoItem.id);
          return scene.assets.loadAsset({
            type: 'video-texture',
            assetId: `video-${videoItem.id}`,
            src: videoItem.src,
            options: { autoPlay: true, loop: true },
          })
        }))
        videos.map((videoTexture, index) => {
          const videoMat = scene.createMaterial(
            scene.assets.getAsset('effect', 'simple'),
            { u_baseColorMap: videoTexture.value.texture }
          )
          scene.assets.addAsset('material', `mat-video-${videoList[index].id}`, videoMat)
        })
        console.log('video asset loaded')
        this.setData({
          videoIdList: videoIdList,
          videoLoaded: true
        })
      } else {
        this.setData({
          videoIdList: [],
          videoLoaded: false
        })
      }
    },

    async _loadVideoSingle(videoItem) {
      console.log('_loadVideoSingle', videoItem);
      const scene = this.scene;
      const assets = this.data.loadedAssets;
      const assetIds = this.data.loadedIdRes;
      try {
        const existingTexture = scene.assets.getAsset('video-texture', `video-${videoItem.id}`);
        console.log('videoText', existingTexture);
        if (existingTexture == undefined) {
          console.log('video type ', videoItem.type);
          let videoEffect = 'simple';
          if (videoItem.type === 'video_alpha') {
            console.log('---video_alpha---');
            const xrFrameSystem = wx.getXrFrameSystem();
            // xrFrameSystem.registerEffect('videoAlpha', createVideoAlphaEffect);
            xrFrameSystem.registerEffect('videoAlpha', () => this.createVideoAlphaEffect(scene));
            videoEffect = 'videoAlpha';
          }
          console.log('video Effect ', videoEffect);
          const videoTexture = await scene.assets.loadAsset({
            type: 'video-texture',
            assetId: `video-` + videoItem.id,
            src: videoItem.src,
            options: { loop: videoItem.options.loop, autoPlay: videoItem.options.autoplay },
          });
          console.log('videoTexture ', videoTexture);
          console.log('videoTexture.value ', videoTexture.value);
          console.log('videoTexture.value ', videoTexture.value.texture);
          const videoMat = scene.createMaterial(
            scene.assets.getAsset('effect', videoEffect),
            { u_baseColorMap: videoTexture.value.texture }
          )
          console.log('videoMat ', videoMat);
          scene.assets.addAsset('material', `mat-video-${videoItem.id}`, videoMat);
          assetIds.push(videoItem.id);
          // assets.push(videoTexture);
        }
        this.setData({
          loadedIdRes: assetIds,
          // loadedAssets: assets,
          videoLoaded: true,
        })
        console.log(`video ${videoItem.id} loaded`);
      } catch (err) {
        console.error(`Failed to load video ${videoItem.id}:`, err);
      }
    },

    createVideoAlphaEffect(scene) {
      const xrFrameSystem = wx.getXrFrameSystem();
      console.log('透明视频特效加载');
      return scene.createEffect({
        name: "videoAlpha",
        properties: [
          {
            key: "u_baseColorFactor",
            type: xrFrameSystem.EUniformType.FLOAT4,
            default: [1, 1, 1, 0]
          }
        ],
        images: [{
          key: "u_baseColorMap",
          default: "white",
          macro: "WX_USE_BASECOLORMAP"
        }],
        defaultRenderQueue: 3000,
        passes: [
          {
            renderStates: {
              cullOn: true,
              blendOn: true,
              depthWrite: true,
              cullFace: xrFrameSystem.ECullMode.BACK
            },
            lightMode: "ForwardBase",
            useMaterialRenderStates: true,
            shaders: [0, 1]
          }],
        shaders: [
          `#version 100
        precision highp float;
        attribute vec3 a_position;
        attribute vec2 a_texCoord;
      
      
        uniform mat4 u_projection;
        uniform mat4 u_world;
        uniform mat4 u_view;
        varying highp vec2 vTextureCoord;
        
        void main()
        {
          vTextureCoord = a_texCoord;
          gl_Position = u_projection * u_view * u_world * vec4(a_position,1.0);
        }`,
          `#version 100
        precision highp float;
      
      
        uniform highp vec4 u_baseColorFactor;
        #ifdef WX_USE_BASECOLORMAP
          uniform sampler2D u_baseColorMap;
        #endif
      
      
        varying highp vec2 vTextureCoord;
      
      
        void main()
        {
      #ifdef WX_USE_BASECOLORMAP
        vec4 color = texture2D(u_baseColorMap, vec2(vTextureCoord.x*0.5,vTextureCoord.y));
        vec4 colora = texture2D(u_baseColorMap, vec2(vTextureCoord.x*0.5 + 0.5,vTextureCoord.y));
      
      
          vec4 baseColor = vec4(color.xyz,colora.x);
      #else
          vec4 baseColor = u_baseColorFactor;
      #endif
       float rgbSum = baseColor.r + baseColor.g + baseColor.b;
      
        gl_FragData[0] = baseColor;
        } 
      `],
      });
    },
    async _loadImages(imageList) {
      console.log('load images:', imageList);
      const scene = this.scene
      if (imageList.length > 0) {
        const imageIdList = [];
        const images = await Promise.all(imageList.map((imageItem) => {
          const id = imageItem.id;
          console.log(imageItem, id);
          imageIdList.push(id);

          // 走 asset 直接加载方式
          return scene.assets.loadAsset({
            type: 'texture',
            assetId: `texture-${imageItem.id}`,
            src: imageItem.src,
          });
        }));

        images.map((texture, index) => {
          const textureMat = scene.createMaterial(
            scene.assets.getAsset('effect', 'simple'),
            { u_baseColorMap: texture.value }
          )
          scene.assets.addAsset('material', `mat-texture-${imageList[index].id}`, textureMat)
        })

        this.setData({
          imageIdList: imageIdList,
          imageLoaded: true
        })
      } else {
        this.setData({
          imageIdList: [],
          imageLoaded: false
        })
      }
    },
    async _loadImage(imageItem) {
      console.log('load image:', imageItem);
      const scene = this.scene;
      if (imageItem && imageItem.id && imageItem.src) {

        // 直接通过 asset 方式加载纹理
        const texture = await scene.assets.loadAsset({
          type: 'texture',
          assetId: `texture-${imageItem.id}`,
          src: imageItem.src,
        });

        // 创建材质并关联纹理
        const textureMat = scene.createMaterial(
          scene.assets.getAsset('effect', 'simple'),
          { u_baseColorMap: texture.value }
        );
        scene.assets.addAsset('material', `mat-texture-${imageItem.id}`, textureMat);

        this.setData({
          imageIdList: [imageItem.id], // 更新已加载的图片ID列表
          imageLoaded: true,
        });
      } else {
        console.warn('Invalid imageItem provided:', imageItem);
        this.setData({
          imageIdList: [],
          imageLoaded: false,
        });
      }
    },
    _releaseGLTF() {
      console.log('_releaseGLTF');
      if (this.data.gltfIdList && this.data.gltfIdList.length > 0) {
        const scene = this.scene
        // 声明使 gltf Mesh 移除
        this.setData({
          gltfLoaded: false
        });
        this.data.gltfIdList.map((id) => {
          // 释放加载过的资源
          scene.assets.releaseAsset('gltf', `gltf-${id}`);
        })
      }
    },
    _releaseVideo() {
      console.log('_releaseVideo');
      if (this.data.videoIdList && this.data.videoIdList.length > 0) {
        const scene = this.scene
        // 声明使视频 Mesh 移除
        this.setData({
          videoLoaded: false
        });
        this.data.videoIdList.map((id) => {
          // 释放加载过的资源
          scene.assets.releaseAsset('video-texture', `video-${id}`);
          scene.assets.releaseAsset('material', `mat-video-${id}`);
        })
      }
    },
    _releaseImage() {
      console.log('_releaseImage');
      if (this.data.imageIdList && this.data.imageIdList.length > 0) {
        const scene = this.scene

        // 声明使视频 Mesh 移除
        this.setData({
          imageLoaded: false
        });

        this.data.imageIdList.map((id) => {
          // 释放加载过的资源
          scene.assets.releaseAsset('texture', `texture-${id}`);
          scene.assets.releaseAsset('material', `mat-texture-${id}`);
        })
      }
    },
    sceneReady: function ({ detail }) {
      console.log('arReady', detail);
      this.setData({
        arReady: true
      });
    },
    releaseVideo(id) {
      console.log('releaseVideo', id);
      if (id !== -1 || id !== undefined) {
        // 存在纹理才进行释放
        const scene = this.scene
        // 释放加载过的资源
        scene.assets.releaseAsset('video-texture', id);
        scene.assets.releaseAsset('material', `mat-video-${id}`);
      }
    },

    changeScene({ detail }) {
      console.log('changeScene', detail);
      const active = detail.value;
      const element = detail.el;
      // console.log('tracked element', element);
      const tradkerId = element.id;
      // console.log('tracked 当前marker id', tradkerId);

      const trackerList = this.data.col;
      // console.log('tracked trackerList', trackerList);
      let curType = '';
      let curResources = [];

      trackerList.forEach(item => {
        console.log('col item', item);
        if (('marker-' + item.id) === tradkerId) {
          curType = item.type;
          // console.log('当前marker type', curType);
          curResources = item.resources;
          // console.log('当前marker resources', item.resources);
          const markerRes = this.data.markerResources;
          // console.log('当前marker markerRes', markerRes);
          if (active) {
            // console.log('loadResources', markerRes);
            this.loadResources(markerRes[item.id], curType);
          }
        }
      });
      this.setData({
        isTracking: !active,
        isTracked: active
      });
      console.log(' 当前marker tracked 状态', active);
      if (active) {
        console.log(' 当前marker curType', curType);
        this.triggerEvent('tracked', {
          value: detail
        });
      } else {
        console.log('videoId', this.videoId);
        this.triggerEvent('lostTrack', {
          value: detail
        });
      }
    },
    async loadResources(res, sceneType = '2dmarker') {
      console.log('loadResources', res);
      const assetIds = this.data.loadedIdRes;
      // const videoIds = this.data.videoIdList;
      // const imageIds = this.data.imageIdList;
      // let type =this.getResourceType(res.id);
      // const resList = this.data.resourceList;

      res.forEach(resItem => {
        console.log('marker resItem', resItem);
        switch (resItem.type) {
          case 'gltf':
            if (!assetIds.includes(resItem.id)) {
              // console.log('动态加载loadResources gltf ', resItem.id);
              this._loadGLTF(resItem);
            } else {
              console.log('已创建 gltf ', resItem.id);
            }
            break;
          case 'video':
            if (!assetIds.includes(resItem.id)) {
              console.log('动态加载loadResources video ', resItem.id);
              console.log('videoId', this.videoId);
              if ((this.videoId !== undefined) && (this.videoId !== -1) && (this.videoId !== resItem.id)) {
                console.log('切换加载视频，旧的需要释放');
                // 处理视频纹理
                this.releaseVideo(this.videoId);
                this.videoId = -1;
              }
              this._loadVideoSingle(resItem);
              this.videoId = resItem.id;
              // this.videoAction(this.videoId, 'play');
            } else {
              console.log('已创建 video ', resItem.id);
            }

            break;
          case 'video_alpha':
            if (!assetIds.includes(resItem.id)) {
              console.log('动态加载loadResources video ', resItem.id);
              console.log('videoId', this.videoId);
              if ((this.videoId !== undefined) && (this.videoId !== -1) && (this.videoId !== resItem.id)) {
                console.log('切换加载视频，旧的需要释放');
                // 处理视频纹理
                this.releaseVideo(this.videoId);
                this.videoId = -1;
              }
              this._loadVideoSingle(resItem);
              this.videoId = resItem.id;
              // this.videoAction(this.videoId, 'play');
            } else {
              console.log('已创建 video ', resItem.id);
            }

            break;
          case 'image':
            console.log('video item info: ', resItem)
            this._loadImageSingle(resItem);
            break;
          default:
            console.log('res item info: ', resItem)
            break;
        }
      });
    },
    videoAction(videoId, eve, val = null) {
      console.log('videoAction', videoId, eve);
      const video = this.scene.assets.getAsset('video-texture', videoId);
      console.log('video', video);
      switch (eve) {
        case 'pause':
          video.pause();
          break;
        case 'play':
          video.play();
          break;
        case 'release':
          video.release();
          break;
        case 'consume':
          video.resume();
          break;
        case 'seek':
          video.seek(val);
          break;
        case 'stop':
          video.stop();
          break;
        default:
          console.log(`videoAction ${eve} is not supported`);
          break;
      }
    },
    tracked({ detail }) {
      console.log('tracked', detail);
      console.log('scene', this.scene);
    },
    error({ detail }) {
      console.log('error', detail);
      this.triggerEvent('arError', {
        value: detail
      });
    }
  },
  ready: function () {
    console.log('outer ready');
  },
})